//
//  Router.swift
//  tenglvBusinessService
//
//  Created by lidi on 2018/12/21.
//  Copyright © 2018 tenglv. All rights reserved.
//

import Foundation

typealias JSONObject = [String:Any]

typealias taskHandle = URLSessionTask?

enum RequestResponse<T> {
    case success(T?,String?)
    case failure(Int,String?)
}

extension Router {
    static var baseUrl:String { return "http://cjwyclient.abcvote.cn" }
}

extension Router {
    static let defaultPage = 1
    static let defaultPageSize = 10
    
    enum SMSType : Int {
        case registe = 1 // 注册
        case modifypasswd = 2 // 重置密码
    }
}

enum Router {
    
    //登录
    case login(phone:String,member_pwd:String)
    
    //发送验证码
    case sendSMS(phone:String,valid_code_type:SMSType)
    
    //注册
    case register(phone:String,member_pwd:String,valid_code:String)
    
    //轮播图列表
    case banner
    
    //首页专题推荐
    case subject
    
    //首页栏目数据接口
    case goods
    
    //猜你喜欢-换一换 通过数据分页,点击换一换切换下一页.通过总数判断页数实现循环切换
    case recommend(pageNum:Int, pageSize:Int, type:Int?)
    
    //发现详情
    case goods_subjectinfo(goods_id:Int)
    
    //所有分类列表
    case goods_catlist
    
    // 电子书分类列表
    case book_catlist
    
    //资源列表,首页更多资源传type值实现各类型资源分页列表，分类筛选传cat_id实现分类筛选数据。
    case goods_list(cat_id:Int?, type:Int?, book_type:Int?, pageNum:Int, pageSize:Int)
    
    // 资源详情
    case goods_info(goods_id:Int, token:String)
    
    // 热词列表
    case hotKeys
    
    // 资源搜索
    case search(searchText:String,type:Int)
    
    // 添加收藏
    case addCollect(goods_id:Int, token:String)
    
    // 移除收藏
    case removeCollect(goods_id:Int, token:String)
    
    // 章节树
    case fetchBookTree(goods_id:Int,token:String)
    
    // 章节内容
    case fetchChapterContent(goods_id:Int,id:Int,token:String)
}

extension Router {
    private var subUrl:String {
        switch self {
        case .login:
            return "/api/web/login"
        case .sendSMS:
            return "/api/web/send/phonecode"
        case .register:
            return "/api/web/register"
        case .banner:
            return "/api/cjwy/index/banner"
        case .subject:
            return "/api/cjwy/index/subject"
        case .goods:
            return "/api/cjwy/index/goods"
        case.recommend:
            return "/api/cjwy/index/recommend"
        case .goods_subjectinfo:
            return "/api/web/goods/subjectinfo"
        case .goods_catlist:
            return "/api/web/goods/catlist"
        case .book_catlist:
            return "/api/web/goods/bookcat/list"
        case .goods_list:
            return "/api/web/goods/list"
        case .goods_info:
            return "/api/web/goods/goodsinfo"
        case .hotKeys:
            return "/api/cjwy/searchcount/list"
        case .search:
            return "/api/web/goods/search"
        case .addCollect:
            return "/api/goods/collect/save"
        case .removeCollect:
            return "/api/goods/collect/remove"
        case .fetchBookTree:
            return "/api/goods/book/tree"
        case .fetchChapterContent:
            return "/api/goods/book/content"
        }
    }
    
    private var parameters:JSONObject {
        var params = JSONObject()
        switch self {
        case let .login(phone, member_pwd):
            params["phone"] = phone
            params["member_pwd"] = member_pwd
        case let .sendSMS(phone, valid_code_type):
            params["phone"] = phone
            params["valid_code_type"] = valid_code_type.rawValue
        case let .register(phone, member_pwd, valid_code):
            params["phone"] = phone
            params["member_pwd"] = member_pwd
            params["valid_code"] = valid_code
        case let .recommend(pageNum, pageSize, type):
            params["pageNum"] = pageNum
            params["pageSize"] = pageSize
            params["type"] = type
        case let .goods_subjectinfo(goods_id):
            params["goods_id"] = goods_id
        case let .goods_list(cat_id, type, book_type, pageNum, pageSize):
            params["cat_id"] = cat_id
            params["type"] = type
            params["book_type"] = book_type
            params["pageNum"] = pageNum
            params["pageSize"] = pageSize
        case let .goods_info(goods_id, token):
            params["goods_id"] = goods_id
            params["token"] = token
        case let .search(searchText, type):
            params["searchText"] = searchText
            params["type"] = type
        case let .addCollect(goods_id, token):
            params["goods_id"] = goods_id
            params["token"] = token
        case let .removeCollect(goods_id, token):
            params["goods_id"] = goods_id
            params["token"] = token
        case let .fetchBookTree(goods_id, token):
            params["goods_id"] = goods_id
            params["token"] = token
        case let .fetchChapterContent(goods_id, id, token):
            params["goods_id"] = goods_id
            params["id"] = id
            params["token"] = token
        default:break
        }
        
        // 加上token
        if AccountManager.shared.isLogin {
            params["token"] = AccountManager.shared.token
        }
        
        return params
    }
    
    private enum HttpMethod {
        case get
        case post
        var value:String {
            switch self {
            case .get:
                return "GET"
            case .post:
                return "POST"
            }
        }
    }
    
    private var httpMethod:HttpMethod {
        return .post
    }
}

extension Router {
    
    var urlRequest:URLRequest {

        var url = Router.baseUrl.appending(self.subUrl)
        // 参数
        let params = self.parameters
        var urlRequest:URLRequest
        
        switch self.httpMethod {
        case .get:
            // 组装
            var paramsArray = [String]()
            for (key,value) in params {
                paramsArray.append("\(key)=\(value)")
            }
            let paramsString = paramsArray.joined(separator: "&")
            if !paramsString.isEmpty {
                url += "?" + paramsString
            }
            urlRequest = URLRequest(url: URL(string: url)!)
        case .post:
            urlRequest = URLRequest(url: URL(string: url)!)
            //let postData = try? JSONSerialization.data(withJSONObject: params, options: .sortedKeys)
            
            var paramsArray = [String]()
            for (key,value) in params {
                paramsArray.append("\(key)=\(value)")
            }
            let paramsString = paramsArray.joined(separator: "&")
            let postData = paramsString.data(using: .utf8)
            
            urlRequest.httpBody = postData
            urlRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        }
        
        urlRequest.httpMethod = self.httpMethod.value
        
        return urlRequest
    }
    
}

extension Router {
    //MARK:通用请求方法
    func request<T>(_ requestResponse:((RequestResponse<T>)->Void)?) -> taskHandle {
        
        //网络请求
        let session = URLSession.shared
        let request = self.urlRequest
        
        let dataTask = session.dataTask(with: request) { (data, respose , error) in
            
            if let httpResponse = respose as? HTTPURLResponse {
                let httpCode = httpResponse.statusCode
                if httpCode == 200 {
                    
                    guard let resData = data else {
                        DispatchQueue.main.async{requestResponse?(.failure(-1,"接口返回data为空"))}
                        return
                    }
                    guard let resDic = try? JSONSerialization.jsonObject(with: resData, options: JSONSerialization.ReadingOptions.allowFragments) else {
                        DispatchQueue.main.async{requestResponse?(.failure(-1,"json解析失败"))}
                        return
                    }
                    guard let resObject = resDic as? JSONObject,!resObject.isEmpty else {
                        DispatchQueue.main.async{requestResponse?(.failure(-1,"接口数据格式不正确"))}
                        return
                    }
                    
                    guard let code = resObject["code"] as? Int else {
                        DispatchQueue.main.async{requestResponse?(.failure(-1,"接口数据格式不正确"))}
                        return
                    }
                    
                    let responseData = resObject["data"] //返回的数据
                    let message = resObject["message"] as? String //message
                    
                    if code == 0 {
                        //请求成功
                        let converted:T? = responseData as? T
                        DispatchQueue.main.async {
                            requestResponse?(.success(converted, message))
                        }
                    } else if code == 600 {
                        // 登录超时，重新登录
                        let loginController = LoginViewController()
                        let navController = CLNavigationController(rootViewController: loginController)
                        UIApplication.shared.keyWindow?.rootViewController?.present(navController, animated: true, completion: nil)
                        
                        DispatchQueue.main.async{requestResponse?(.failure(code,message))}
                     }
                    else {
                        DispatchQueue.main.async{requestResponse?(.failure(code,message))}
                    }
                    
                } else {
                    let message = "\(httpCode) \(HTTPURLResponse.localizedString(forStatusCode: httpCode))"
                    DispatchQueue.main.async{requestResponse?(.failure(httpCode,message))}
                }
            } else {
                DispatchQueue.main.async{requestResponse?(.failure(-1,"网络异常"))}
            }
            
        }
        
        dataTask.resume()
        return dataTask
    }
}
